package com.kexilo.core.common.config.application;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.boot.actuator.health.Health;
// import org.springframework.boot.actuator.health.HealthIndicator;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;

/**
 * 自定义系统监控组件
 * 
 * @author Kexilo
 */
@Component("kexilo")
public class CustomHealthIndicator {
    
    private static final Logger log = LoggerFactory.getLogger(CustomHealthIndicator.class);
    
    @Autowired
    private DataSource dataSource;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 获取系统健康状态
     * 
     * @return 系统状态信息
     */
    public SystemStatus getSystemHealth() {
        SystemStatus status = new SystemStatus();
        
        try {
            // 检查数据库连接
            boolean dbHealthy = checkDatabase();
            
            // 检查Redis连接
            boolean redisHealthy = checkRedis();
            
            // 检查系统资源
            SystemStatus systemStatus = checkSystemResources();
            
            status.setDatabaseHealthy(dbHealthy);
            status.setRedisHealthy(redisHealthy);
            // 简化系统状态设置
            status.setMemoryUsage(systemStatus.memoryUsage);
            status.setDiskUsage(systemStatus.diskUsage);
            status.setCpuLoad(systemStatus.cpuLoad);
            status.setActiveThreads(systemStatus.activeThreads);
            status.setTimestamp(System.currentTimeMillis());
            status.setHealthy(dbHealthy && redisHealthy && systemStatus.isHealthy());
            
        } catch (Exception e) {
            log.error("健康检查异常：{}", e.getMessage(), e);
            status.setHealthy(false);
            status.setError(e.getMessage());
            status.setTimestamp(System.currentTimeMillis());
        }
        
        return status;
    }
    
    /**
     * 检查数据库连接
     * 
     * @return 是否健康
     */
    private boolean checkDatabase() {
        try (Connection connection = dataSource.getConnection()) {
            return connection.isValid(5); // 5秒超时
        } catch (SQLException e) {
            log.error("数据库健康检查失败：{}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 检查Redis连接
     * 
     * @return 是否健康
     */
    private boolean checkRedis() {
        try {
            String testKey = "health:check:" + System.currentTimeMillis();
            redisTemplate.opsForValue().set(testKey, "test", 10, TimeUnit.SECONDS);
            String value = (String) redisTemplate.opsForValue().get(testKey);
            redisTemplate.delete(testKey);
            return "test".equals(value);
        } catch (Exception e) {
            log.error("Redis健康检查失败：{}", e.getMessage());
            return false;
        }
    }
    
    /**
     * 检查系统资源
     * 
     * @return 系统状态
     */
    private SystemStatus checkSystemResources() {
        Runtime runtime = Runtime.getRuntime();
        
        // 内存检查
        long maxMemory = runtime.maxMemory();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        double memoryUsage = (double) usedMemory / maxMemory;
        
        // 线程检查
        int activeThreads = Thread.activeCount();
        
        // CPU检查（通过系统负载）
        double cpuLoad = getSystemCpuLoad();
        
        // 磁盘检查
        double diskUsage = getDiskUsage();
        
        SystemStatus status = new SystemStatus();
        status.setMemoryUsage(memoryUsage);
        status.setActiveThreads(activeThreads);
        status.setCpuLoad(cpuLoad);
        status.setDiskUsage(diskUsage);
        
        // 健康阈值判断
        boolean healthy = memoryUsage < 0.9 && // 内存使用率低于90%
                         activeThreads < 1000 && // 活跃线程数少于1000
                         cpuLoad < 0.8 && // CPU负载低于80%
                         diskUsage < 0.9; // 磁盘使用率低于90%
        
        status.setHealthy(healthy);
        
        return status;
    }
    
    /**
     * 获取系统CPU负载
     * 
     * @return CPU负载百分比
     */
    private double getSystemCpuLoad() {
        try {
            com.sun.management.OperatingSystemMXBean osBean = 
                (com.sun.management.OperatingSystemMXBean) java.lang.management.ManagementFactory.getOperatingSystemMXBean();
            return osBean.getSystemCpuLoad();
        } catch (Exception e) {
            return 0.0;
        }
    }
    
    /**
     * 获取磁盘使用率
     * 
     * @return 磁盘使用率百分比
     */
    private double getDiskUsage() {
        try {
            java.io.File file = new java.io.File(".");
            long totalSpace = file.getTotalSpace();
            long freeSpace = file.getFreeSpace();
            long usedSpace = totalSpace - freeSpace;
            return totalSpace > 0 ? (double) usedSpace / totalSpace : 0.0;
        } catch (Exception e) {
            return 0.0;
        }
    }
    
    /**
     * 系统状态类
     */
    private static class SystemStatus {
        private boolean healthy;
        private double memoryUsage;
        private int activeThreads;
        private double cpuLoad;
        private double diskUsage;
        private boolean databaseHealthy;
        private boolean redisHealthy;
        private long timestamp;
        private String error;
        
        public boolean isHealthy() {
            return healthy;
        }
        
        public void setHealthy(boolean healthy) {
            this.healthy = healthy;
        }
        
        public void setMemoryUsage(double memoryUsage) {
            this.memoryUsage = memoryUsage;
        }
        
        public void setActiveThreads(int activeThreads) {
            this.activeThreads = activeThreads;
        }
        
        public void setCpuLoad(double cpuLoad) {
            this.cpuLoad = cpuLoad;
        }
        
        public void setDiskUsage(double diskUsage) {
            this.diskUsage = diskUsage;
        }
        
        public String getMemoryStatus() {
            return String.format("使用率: %.1f%%", memoryUsage * 100);
        }
        
        public String getDiskStatus() {
            return String.format("使用率: %.1f%%", diskUsage * 100);
        }
        
        public String getCpuStatus() {
            return String.format("负载: %.1f%%", cpuLoad * 100);
        }
        
        public String getThreadStatus() {
            return String.format("活跃线程: %d", activeThreads);
        }
        
        public void setDatabaseHealthy(boolean databaseHealthy) {
            this.databaseHealthy = databaseHealthy;
        }
        
        public void setRedisHealthy(boolean redisHealthy) {
            this.redisHealthy = redisHealthy;
        }
        
        public void setTimestamp(long timestamp) {
            this.timestamp = timestamp;
        }
        
        public void setError(String error) {
            this.error = error;
        }
    }
}
